<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		<div id="app">
			<h2>
				<p>hello</p>
				<p>{{show}}</p>
			</h2>
			<p>1</p>
			<p>2</p>
			<p>3</p>
			<p>4</p>
			<p>5</p>
			<p>6</p>
			<p>7</p>
			<p>8</p>
			<p>9</p>
			<p>10</p>
			<p>11</p>
			<p>12</p>
			<p>13</p>
			<p>14</p>
			<p>15</p>
			<p>16</p>
			<p>17</p>
			<p>18</p>
			<p>19</p>
			<p>20</p>
			<div>div</div>
			<p>ppp</p>
			<ul>
				<li v-for='item in list' :key='item'>{{item}}</li>
			</ul>
			<button @click='change'>修改</button>
			<button @click='show=!show'>显示/隐藏</button>
		</div>
		<script src="./vue.js"></script>
		<script>
			new Vue({
				el:'#app',
				data:{
					show:false,
					list:[1,4,5,6],
				},
				methods: {
					change() {
						this.list.push(9)
					}
				}
			})
		</script>
		<!-- 
			面试题
			https://blog.csdn.net/qq_22182989/article/details/125781704
			https://zhuanlan.zhihu.com/p/522659518?utm_id=0
		
		vue3  vue3跟vue2的区别
		
		配置api  组合式api
		
		新增一个内置组件  3  Fragment  Teleport  Suspense
		
		生命周期的改变  bc  c  setup    unmounted
		
		全局的api  ...Vue.  app.
		
		响应式的升级 ...
		defineProperty     数组下标修改数组   修改数组长度    给对象新增属性  给对象删除属性  无法监听没有响应式
		vue3 响应式升级  基础数据类型 依然还是 defineProperty  复杂数据类型 通过 proxy实现的
		
		
		整个流程->数据改变->内部setter->Dep.notify方法->patch(oldnode,newnode)
		  
		
		vue3 - vue2   性能优化  体现
			
			
		diff算法
		?什么是虚拟DOM  
		当页面发生变化-vue封装了一个方法 用来比较两个虚拟dom 最小化的更新视图
		
		整个流程->数据改变->内部setter->Dep.notify方法->patch(oldnode,newnode)
		
		① 先比对是不是同类标签 如果不是就直接替换
		② 是同类 比对 新旧node 是否相等 相等 直接 return 没必要比对
		③ 不相等分情况比对 
			新旧node都有 文本节点  直接替换文本节点
			old没有子节点 新的有子节点 直接添加子节点   
			旧的有子节点 新的没有子节点  直接删除子节点
			新旧都有子节点 -> updateChildren 比对子节点
		updateChildren   图 https://zhuanlan.zhihu.com/p/149966206
			首尾指针法   旧节点 有 一个 开始 一个结束节点  新节点 也有一个开始一个结束节点
			比较顺序  os-ns  os-ne   oe-ns  oe-ne 
			比对成功后 start节点 向右移动  old节点 向左
			如果 有任意的  start节点在 end后面则比对结束 ,如果old节点还有没比对的内容 则删除,如果新的节点还有没比对的内容 则添加
			
			如果都匹配不到则比对新旧节点的 key值 key相同则复用 并且移动到新虚拟DOM的位置
			key为什么不建议 是index
			
		
		响应式系统升级
			使用 Proxy 对象重写响应式系统：vue2.x 中 使用 defineProperty 在初始化时遍历 data 中的成员，实现响应式，
			若成员中嵌套成员则递归实现 get 、set ,如果 data 中的成员未被使用，也会做响应式处理的操作。但在 Vue3 中，只
			有在成员被用到的时候才会处理响应式
			
			Vue2  vue3响应式的区别 
			 vue2全部 defineProperty   
			vue3  基本数据类型  defineProperty   引用数据量  Proxy 
			
			可以监听动态新增的属性
			
			可以监听删除的属性
			
			可以监听数组的索引和 length 属性
			arr[0] = 666
			
			
	vue3基于 vue2 性能提升  体现再 （从源码的角度）   静态提升 预字符串化 缓存事件处理函数  BlockTree
			
		 静态提升 
		 
			静态节点   纯元素节点 没有动态的内容 
			
			
			vue2 
			render(){
				createVNode('h1',null,'hello world')
			}
			vue3 
			const hoisted = createVNode('h1',null,'helloword')
			function render(){
				直接使用 hoisted
			}
			因为  render 函数 每一次修改数据都会重新运行
			
			静态属性提升
			<div class="box">
				{{message}}
			</div>
			
			const hoisted = {class:'box'}
			 function render(){
				直接使用 hoisted
			 }
		 预字符串化 
		 Vue 3 在编译时会进行静态提升节点的 预字符串化。什么是预字符串化呢？一起来看个示例：
		 <template>
		   <p></p>
		   ... 共 20+ 节点
		   <p></p>
		 </template>
		 对于这样有大量静态提升的模版场景，如果不考虑 预字符串化 那么生成的渲染函数将会包含大量的 createElementVNode 函数
		 
		 
		 createElementVNode 大量连续性创建 vnode 也是挺影响性能的，所以可以通过 预字符串化 来一次性创建这些静态节点，采
		 用 预字符串化 后，生成的渲染函数如下：
		 const hoisted = createStaticVNode("<p></p>...<p></p>", 20)
		 这样一方面降低了 createElementVNode 连续创建带来的性能损耗，也侧面减少了代码体积。
		 
		 缓存事件处理函数
			比如存在如下事件处理函数
			<button @click="count++">plus</button>
			// vue2
			render(ctx){
			  return createVNode("button", {
			    onClick: function($event){
			      ctx.count++;
			    }
			  })
			}
			// vue3
			render(ctx, cache){
			  return createVNode("button", {
			    onClick: cache[0] || (cache[0] = ($event) => (ctx.count++))
			  })
			}

			对比vue2和vue3的处理方式
			在vue2中创建一个虚拟节点button，属性里面多了一个事件onclick，内容就是count++。在vue3
			中会认为这里的事件处理是不会变化的，不是说这次渲染是事件函数，下次就变成别的，于是vue3会智
			能地发现这一点，会做缓存处理，它首先会看一看缓存里面有没有这个事件函数，有的话直接返回，没
			有的话就直接赋值为一个count++函数，保证事件处理函数只生成一次。
		 
		 Block Tree
			vue2在对比新旧树的时候，并不知道哪些节点是静态的，哪些是动态的，因此只能一层一层比较，这就浪费了大部分时间在比对静态节点上
			<div>
			  <div>HelloVue!</div>
			  <p>{{ text }}</p>
			</div> 
			vue2 虚拟dom
			{
			  tag:'div',
			  children:[
			  {tag:'div',children:'HelloVue'},
			  {tag:'p,children: _context.text}
			  ]
			} 
			vue3 虚拟dom
			{
			  tag:'div',
			  children:[
			  {tag:'div',children:'HelloVue'},
			  //patchFlag等于1说明这个节点的textContent是动态内容
			  {tag:'p,children: _context.text，patchFlag: 1 } 
			  ]
			} 
			patchFlag属性可以让运行时知道这个vnode是一个含有动态内容的vnode（后面简称动态vnode），而且根据这个属
			性的值还可以精准的判断标签的动态部分到底在哪。所以可以在创建VNode的时候，把Vnode子节点中的被patchFlag
			标记的动态vnode提取出来（这个提取过程后面会讲到），保存在它自己的dynamicChildren数组内。我们把含有这
			个dynamicChildren数组的VNode就叫做一个block，block不只会提取到children的动态VNode，还可以提取到
			所有子代动态VNode。
		
		 
		 -->
	</body>
</html>